package com.jy.rhin.infra.repo.notfication.participant.query;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.jy.framework.base.entity.Page;
import com.jy.rhin.domain.notification.participant.entity.EnumParticipantRole;
import com.jy.rhin.domain.notification.participant.entity.ParticipantDO;
import com.jy.rhin.infra.repo.notfication.participant.mapper.ParticipantMapper;
import com.jy.rhin.infra.repo.notfication.participant.po.ParticipantPO;
import com.jy.rhin.sdk.dto.notification.PublisherDto;
import com.jy.rhin.sdk.dto.notification.PublisherShortDto;
import com.jy.rhin.sdk.dto.notification.SubscriberDto;
import com.jy.rhin.sdk.dto.notification.SubscriberShortDto;
import com.jy.rhin.sdk.dto.notification.req.PublisherOrSubscriberReqDto;
import com.jy.starter.repository.utils.PageUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author dhl
 * @date 2022/6/29
 * @Description
 */
@Service
public class ParticipantQueryHandler {

    @Resource
    private ParticipantMapper participantMapper;

    /**
     * 发布者分页查询
     * @param req
     * @return
     */
    public Page<PublisherDto> queryPublisherPage(PublisherOrSubscriberReqDto req) {
        Page<ParticipantPO> pageResult = queryData(req.getName(), req.getCurrent(), req.getSize(), EnumParticipantRole.PUBLISHER.name());
        List<PublisherDto> list = pageResult.getRecords().stream().map(this::publisherConvert).collect(Collectors.toList());
        Page<PublisherDto> result = new Page<>();
        BeanUtils.copyProperties(pageResult, result);
        result.setRecords(list);
        return result;
    }

    /**
     * 发布者列表查询
     * @return
     */
    public List<PublisherShortDto> queryPublisherList() {
        List<ParticipantPO> poList = queryAllParticipantListByRole(EnumParticipantRole.PUBLISHER);

        return poList.stream().map(po -> {
            PublisherShortDto resp = new PublisherShortDto();
            resp.setPublisherCode(po.getParticipantCode());
            resp.setPublisherName(po.getParticipantName());
            return resp;
        }).collect(Collectors.toList());
    }

    /**
     * 订阅者分页查询
     * @param req
     * @return
     */
    public Page<SubscriberDto> querySubscriberPage(PublisherOrSubscriberReqDto req) {
        Page<ParticipantPO> pageResult = queryData(req.getName(), req.getCurrent(), req.getSize(), EnumParticipantRole.SUBSCRIBER.name());
        List<SubscriberDto> list = pageResult.getRecords().stream().map(this::subscriberConvert).collect(Collectors.toList());
        Page<SubscriberDto> result = new Page<>();
        BeanUtils.copyProperties(pageResult, result);
        result.setRecords(list);
        return result;
    }

    /**
     * 订阅者列表查询
     * @return
     */
    public List<SubscriberShortDto> querySubscriberList() {
        List<ParticipantPO> poList = queryAllParticipantListByRole(EnumParticipantRole.SUBSCRIBER);

        return poList.stream().map(po -> {
            SubscriberShortDto resp = new SubscriberShortDto();
            resp.setSubscriberCode(po.getParticipantCode());
            resp.setSubscriberName(po.getParticipantName());
            return resp;
        }).collect(Collectors.toList());
    }

    /**
     * 根据参与者编码和角色查询参与者
     * @param code
     * @param role
     * @return
     */
    public ParticipantDO queryByCodeAndRole(String code, EnumParticipantRole role) {
        QueryWrapper<ParticipantPO> query = new QueryWrapper<>();
        query.lambda().eq(ParticipantPO::getParticipantCode, code);
        query.lambda().eq(ParticipantPO::getParticipantRole, role.name());
        ParticipantPO po = participantMapper.selectOne(query);
        return ObjectUtils.isNull(po) ? null : po.toDO();
    }

    /**
     * 根据角色查询全部数据列表
     * @param role
     * @return
     */
    private List<ParticipantPO> queryAllParticipantListByRole(EnumParticipantRole role) {
        QueryWrapper<ParticipantPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ParticipantPO::getParticipantRole, role.name())
                .orderByDesc(ParticipantPO::getCreateTime);
        return participantMapper.selectList(queryWrapper);
    }

    /**
     * 发mq消息需要根据code列表查到所有订阅者
     * @param subscriberList
     */
    public List<SubscriberDto> queryPublisherListByCodeList(Set<String> subscriberList) {
        QueryWrapper<ParticipantPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ParticipantPO::getParticipantRole, EnumParticipantRole.SUBSCRIBER)
                .in(ParticipantPO::getParticipantCode, subscriberList)
                .orderByDesc(ParticipantPO::getCreateTime);
        List<ParticipantPO> poList = participantMapper.selectList(queryWrapper);

        return CollectionUtils.isEmpty(poList)? Collections.emptyList() : poList.stream().map(this::subscriberConvert).collect(Collectors.toList());
    }

    /**
     * db数据查询
     * @param name
     * @param pageNo
     * @param pageSize
     * @param roleName
     * @return
     */
    private Page<ParticipantPO> queryData(String name, Integer pageNo, Integer pageSize, String roleName) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ParticipantPO> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize, true);
        QueryWrapper<ParticipantPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ParticipantPO::getParticipantRole, roleName)
                .like(!StringUtils.isEmpty(name), ParticipantPO::getParticipantName, name)
                .orderByDesc(ParticipantPO::getCreateTime);
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ParticipantPO> resultPage = participantMapper.selectPage(page, queryWrapper);
        return PageUtils.page(resultPage);
    }

    /**
     * 参与者转发布者
     * @param po
     * @return
     */
    private PublisherDto publisherConvert(ParticipantPO po) {
        PublisherDto respDto = new PublisherDto();
        respDto.setId(po.getId());
        respDto.setPublisherName(po.getParticipantName());
        respDto.setPublisherCode(po.getParticipantCode());
        respDto.setPublisherUrl(po.getParticipantUrl());
        respDto.setPublisherDesc(po.getParticipantDesc());
        respDto.setCreateBy(po.getCreateBy());
        respDto.setCreateTime(po.getCreateTime());
        respDto.setUpdateBy(po.getUpdateBy());
        respDto.setUpdateTime(po.getUpdateTime());
        return respDto;
    }

    /**
     * 参与者转订阅者
     * @param po
     * @return
     */
    private SubscriberDto subscriberConvert(ParticipantPO po) {
        SubscriberDto respDto = new SubscriberDto();
        respDto.setId(po.getId());
        respDto.setSubscriberName(po.getParticipantName());
        respDto.setSubscriberCode(po.getParticipantCode());
        respDto.setSubscriberUrl(po.getParticipantUrl());
        respDto.setSubscriberDesc(po.getParticipantDesc());
        respDto.setInteractionType(po.getInteractionType());
        respDto.setCreateBy(po.getCreateBy());
        respDto.setCreateTime(po.getCreateTime());
        respDto.setUpdateBy(po.getUpdateBy());
        respDto.setUpdateTime(po.getUpdateTime());
        return respDto;
    }


}
